/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import java.util.ArrayList;
import org.apache.log4j.Logger;

/**
 *
 * @author Sakis Vtdk
 */

public abstract class SqlScriptGenerator
{

	public abstract String getSqlScript();

	public abstract String getSqlScript(ArrayList<Change> changeSet);

	/**
	 * Maintains an ArrayList of temporary columns on which each change is applied
	 * so that the getDefinition() method will generate the correct definition
	 * based on the changes made at any given point
	 * 
	 * @param columnChange 
	 */
	public void updateTmpColumns(Change columnChange) 
	{
		if(columnChange.getObjectChanged().equals(Change.ObjectChanged.COLUMN.toString()))
		{
			TableColumn tmpColumn = null;
			if(columnChange.getType().equals(Change.Type.CREATE.toString()))
			{
				tmpColumn = new TableColumn(columnChange.getName());
				tmpColumn.setId(columnChange.getId());
				tmpColumn.setParentId(columnChange.getParentId());
				this._tmpColumns.add(tmpColumn);
			}
			else if(columnChange.getType().equals(Change.Type.UPDATE.toString()))
			{
				//first find the column
				tmpColumn = getColumn(columnChange);

				//then update it
				if(columnChange.getWhatChanged().equals(Change.WhatChanged.NAME.toString()))
				{
					tmpColumn.setName(columnChange.getNewValue());
				}
				else if(columnChange.getWhatChanged().equals(Change.WhatChanged.DATA_TYPE.toString()))
				{
					tmpColumn.setDataType(columnChange.getNewValue());
				}
				else if(columnChange.getWhatChanged().equals(Change.WhatChanged.DATA_SIZE.toString()))
				{
					Integer tmpSize = Integer.parseInt(columnChange.getNewValue());
					tmpColumn.setSize(tmpSize);
				}
				else if(columnChange.getWhatChanged().equals(Change.WhatChanged.DEFAULT_VALUE.toString()))
				{
					tmpColumn.setDefaultValue(columnChange.getNewValue());
				}
				else if(columnChange.getWhatChanged().equals(Change.WhatChanged.AUTO_INCREMENT.toString()))
				{
					tmpColumn.setAutoIncrement(Boolean.parseBoolean(columnChange.getNewValue()));
				}
				else if(columnChange.getWhatChanged().equals(Change.WhatChanged.PRIMARY_KEY.toString()))
				{
					tmpColumn.setPrimaryKey(Boolean.parseBoolean(columnChange.getNewValue()));
				}
			}
		}
	}

	/**
	 * Selects a column from the ArrayList of temporary columns based on the 
	 * {@link Change} passed as an argument
	 * 
	 * @param columnChange
	 * @throws Exception An exception is thrown if a database snapshot can not be loaded
	 * @return The column found, or null if there was no such column
	 */
	protected TableColumn getColumn(Change columnChange) 
	{
		TableColumn tmpColumn = null;
		//find the correct column
		for(TableColumn col : this._tmpColumns)
		{
			if(col.getParentId() == columnChange.getParentId() && col.getId() == columnChange.getId())
			{
				tmpColumn = col;
				break;
			}
		}

		//if this column was not in this ArrayList
		//(e.g. if the first change is an UPDATE to move from one version
		//to NEXT), we try to retrieve the columns from the PREVIOUS version
		if(tmpColumn == null && !columnChange.isReverse())
		{
			try
			{
				tmpColumn = Database.retrieveSnapShot(Database.getDatabase().getPreviousVersion()).getTable(columnChange.getParentId()).getColumn(columnChange.getId()).clone();
				Database.restoreWorkingInstance();
			}
			catch(Exception ex)
			{
				log.error("Could not retrieve the requested snapshot. Exception error: "+ ex.getMessage());
			}

			this._tmpColumns.add(tmpColumn);
		}
		else if(tmpColumn == null && columnChange.isReverse())
		{
			try
			{
				tmpColumn = Database.getDatabase().getTable(columnChange.getParentId()).getColumn(columnChange.getId()).clone();
			}
			catch(Exception ex)
			{
				log.error("Could not retrieve the requested snapshot. Exception error: "+ ex.getMessage());
			}

			this._tmpColumns.add(tmpColumn);
		}

		return tmpColumn;
	}

	/**
	 * Temporary columns of the database, used to get the correct definitions 
	 * when creating an SQL script
	 */
	protected ArrayList<TableColumn> _tmpColumns = new ArrayList<TableColumn>();
	private static Logger log = Logger.getLogger(SqlScriptGenerator.class);
}
